home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / interp / perl5.005.tar.gz / perl5.005.tar / perl5.005 / doop.c < prev    next >
C/C++ Source or Header  |  1998-07-19  |  11KB  |  529 lines

  1. /*    doop.c
  2.  *
  3.  *    Copyright (c) 1991-1997, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  */
  9.  
  10. /*
  11.  * "'So that was the job I felt I had to do when I started,' thought Sam."
  12.  */
  13.  
  14. #include "EXTERN.h"
  15. #include "perl.h"
  16.  
  17. #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
  18. #include <signal.h>
  19. #endif
  20.  
  21. I32
  22. do_trans(SV *sv, OP *arg)
  23. {
  24.     dTHR;
  25.     register short *tbl;
  26.     register U8 *s;
  27.     register U8 *send;
  28.     register U8 *d;
  29.     register I32 ch;
  30.     register I32 matches = 0;
  31.     register I32 squash = PL_op->op_private & OPpTRANS_SQUASH;
  32.     register U8 *p;
  33.     STRLEN len;
  34.  
  35.     if (SvREADONLY(sv) && !(PL_op->op_private & OPpTRANS_COUNTONLY))
  36.     croak(no_modify);
  37.     tbl = (short*)cPVOP->op_pv;
  38.     s = (U8*)SvPV(sv, len);
  39.     if (!len)
  40.     return 0;
  41.     if (!SvPOKp(sv))
  42.     s = (U8*)SvPV_force(sv, len);
  43.     (void)SvPOK_only(sv);
  44.     send = s + len;
  45.     if (!tbl || !s)
  46.     croak("panic: do_trans");
  47.     DEBUG_t( deb("2.TBL\n"));
  48.     if (!PL_op->op_private) {
  49.     while (s < send) {
  50.         if ((ch = tbl[*s]) >= 0) {
  51.         matches++;
  52.         *s = ch;
  53.         }
  54.         s++;
  55.     }
  56.     SvSETMAGIC(sv);
  57.     }
  58.     else if (PL_op->op_private & OPpTRANS_COUNTONLY) {
  59.     while (s < send) {
  60.         if (tbl[*s] >= 0)
  61.         matches++;
  62.         s++;
  63.     }
  64.     }
  65.     else {
  66.     d = s;
  67.     p = send;
  68.     while (s < send) {
  69.         if ((ch = tbl[*s]) >= 0) {
  70.         *d = ch;
  71.         matches++;
  72.         if (squash) {
  73.             if (p == d - 1 && *p == *d)
  74.             matches--;
  75.             else
  76.                 p = d++;
  77.         }
  78.         else
  79.             d++;
  80.         }
  81.         else if (ch == -1)        /* -1 is unmapped character */
  82.         *d++ = *s;        /* -2 is delete character */
  83.         s++;
  84.     }
  85.     matches += send - d;    /* account for disappeared chars */
  86.     *d = '\0';
  87.     SvCUR_set(sv, d - (U8*)SvPVX(sv));
  88.     SvSETMAGIC(sv);
  89.     }
  90.     return matches;
  91. }
  92.  
  93. void
  94. do_join(register SV *sv, SV *del, register SV **mark, register SV **sp)
  95. {
  96.     SV **oldmark = mark;
  97.     register I32 items = sp - mark;
  98.     register STRLEN len;
  99.     STRLEN delimlen;
  100.     register char *delim = SvPV(del, delimlen);
  101.     STRLEN tmplen;
  102.  
  103.     mark++;
  104.     len = (items > 0 ? (delimlen * (items - 1) ) : 0);
  105.     if (SvTYPE(sv) < SVt_PV)
  106.     sv_upgrade(sv, SVt_PV);
  107.     if (SvLEN(sv) < len + items) {    /* current length is way too short */
  108.     while (items-- > 0) {
  109.         if (*mark && !SvGMAGICAL(*mark) && SvOK(*mark)) {
  110.         SvPV(*mark, tmplen);
  111.         len += tmplen;
  112.         }
  113.         mark++;
  114.     }
  115.     SvGROW(sv, len + 1);        /* so try to pre-extend */
  116.  
  117.     mark = oldmark;
  118.     items = sp - mark;;
  119.     ++mark;
  120.     }
  121.  
  122.     if (items-- > 0) {
  123.     char *s;
  124.  
  125.     if (*mark) {
  126.         s = SvPV(*mark, tmplen);
  127.         sv_setpvn(sv, s, tmplen);
  128.     }
  129.     else
  130.         sv_setpv(sv, "");
  131.     mark++;
  132.     }
  133.     else
  134.     sv_setpv(sv,"");
  135.     len = delimlen;
  136.     if (len) {
  137.     for (; items > 0; items--,mark++) {
  138.         sv_catpvn(sv,delim,len);
  139.         sv_catsv(sv,*mark);
  140.     }
  141.     }
  142.     else {
  143.     for (; items > 0; items--,mark++)
  144.         sv_catsv(sv,*mark);
  145.     }
  146.     SvSETMAGIC(sv);
  147. }
  148.  
  149. void
  150. do_sprintf(SV *sv, I32 len, SV **sarg)
  151. {
  152.     STRLEN patlen;
  153.     char *pat = SvPV(*sarg, patlen);
  154.     bool do_taint = FALSE;
  155.  
  156.     sv_vsetpvfn(sv, pat, patlen, Null(va_list*), sarg + 1, len - 1, &do_taint);
  157.     SvSETMAGIC(sv);
  158.     if (do_taint)
  159.     SvTAINTED_on(sv);
  160. }
  161.  
  162. void
  163. do_vecset(SV *sv)
  164. {
  165.     SV *targ = LvTARG(sv);
  166.     register I32 offset;
  167.     register I32 size;
  168.     register unsigned char *s;
  169.     register unsigned long lval;
  170.     I32 mask;
  171.     STRLEN targlen;
  172.     STRLEN len;
  173.  
  174.     if (!targ)
  175.     return;
  176.     s = (unsigned char*)SvPV_force(targ, targlen);
  177.     lval = U_L(SvNV(sv));
  178.     offset = LvTARGOFF(sv);
  179.     size = LvTARGLEN(sv);
  180.     
  181.     len = (offset + size + 7) / 8;
  182.     if (len > targlen) {
  183.     s = (unsigned char*)SvGROW(targ, len + 1);
  184.     (void)memzero(s + targlen, len - targlen + 1);
  185.     SvCUR_set(targ, len);
  186.     }
  187.     
  188.     if (size < 8) {
  189.     mask = (1 << size) - 1;
  190.     size = offset & 7;
  191.     lval &= mask;
  192.     offset >>= 3;
  193.     s[offset] &= ~(mask << size);
  194.     s[offset] |= lval << size;
  195.     }
  196.     else {
  197.     offset >>= 3;
  198.     if (size == 8)
  199.         s[offset] = lval & 255;
  200.     else if (size == 16) {
  201.         s[offset] = (lval >> 8) & 255;
  202.         s[offset+1] = lval & 255;
  203.     }
  204.     else if (size == 32) {
  205.         s[offset] = (lval >> 24) & 255;
  206.         s[offset+1] = (lval >> 16) & 255;
  207.         s[offset+2] = (lval >> 8) & 255;
  208.         s[offset+3] = lval & 255;
  209.     }
  210.     }
  211. }
  212.  
  213. void
  214. do_chop(register SV *astr, register SV *sv)
  215. {
  216.     STRLEN len;
  217.     char *s;
  218.     
  219.     if (SvTYPE(sv) == SVt_PVAV) {
  220.     register I32 i;
  221.         I32 max;
  222.     AV* av = (AV*)sv;
  223.         max = AvFILL(av);
  224.         for (i = 0; i <= max; i++) {
  225.         sv = (SV*)av_fetch(av, i, FALSE);
  226.         if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef))
  227.         do_chop(astr, sv);
  228.     }
  229.         return;
  230.     }
  231.     if (SvTYPE(sv) == SVt_PVHV) {
  232.         HV* hv = (HV*)sv;
  233.     HE* entry;
  234.         (void)hv_iterinit(hv);
  235.         /*SUPPRESS 560*/
  236.         while (entry = hv_iternext(hv))
  237.             do_chop(astr,hv_iterval(hv,entry));
  238.         return;
  239.     }
  240.     s = SvPV(sv, len);
  241.     if (len && !SvPOK(sv))
  242.     s = SvPV_force(sv, len);
  243.     if (s && len) {
  244.     s += --len;
  245.     sv_setpvn(astr, s, 1);
  246.     *s = '\0';
  247.     SvCUR_set(sv, len);
  248.     SvNIOK_off(sv);
  249.     }
  250.     else
  251.     sv_setpvn(astr, "", 0);
  252.     SvSETMAGIC(sv);
  253.  
  254. I32
  255. do_chomp(register SV *sv)
  256. {
  257.     dTHR;
  258.     register I32 count;
  259.     STRLEN len;
  260.     char *s;
  261.  
  262.     if (RsSNARF(PL_rs))
  263.     return 0;
  264.     count = 0;
  265.     if (SvTYPE(sv) == SVt_PVAV) {
  266.     register I32 i;
  267.         I32 max;
  268.     AV* av = (AV*)sv;
  269.         max = AvFILL(av);
  270.         for (i = 0; i <= max; i++) {
  271.         sv = (SV*)av_fetch(av, i, FALSE);
  272.         if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef))
  273.         count += do_chomp(sv);
  274.     }
  275.         return count;
  276.     }
  277.     if (SvTYPE(sv) == SVt_PVHV) {
  278.         HV* hv = (HV*)sv;
  279.     HE* entry;
  280.         (void)hv_iterinit(hv);
  281.         /*SUPPRESS 560*/
  282.         while (entry = hv_iternext(hv))
  283.             count += do_chomp(hv_iterval(hv,entry));
  284.         return count;
  285.     }
  286.     s = SvPV(sv, len);
  287.     if (len && !SvPOKp(sv))
  288.     s = SvPV_force(sv, len);
  289.     if (s && len) {
  290.     s += --len;
  291.     if (RsPARA(PL_rs)) {
  292.         if (*s != '\n')
  293.         goto nope;
  294.         ++count;
  295.         while (len && s[-1] == '\n') {
  296.         --len;
  297.         --s;
  298.         ++count;
  299.         }
  300.     }
  301.     else {
  302.         STRLEN rslen;
  303.         char *rsptr = SvPV(PL_rs, rslen);
  304.         if (rslen == 1) {
  305.         if (*s != *rsptr)
  306.             goto nope;
  307.         ++count;
  308.         }
  309.         else {
  310.         if (len < rslen - 1)
  311.             goto nope;
  312.         len -= rslen - 1;
  313.         s -= rslen - 1;
  314.         if (memNE(s, rsptr, rslen))
  315.             goto nope;
  316.         count += rslen;
  317.         }
  318.     }
  319.     *s = '\0';
  320.     SvCUR_set(sv, len);
  321.     SvNIOK_off(sv);
  322.     }
  323.   nope:
  324.     SvSETMAGIC(sv);
  325.     return count;
  326.  
  327. void
  328. do_vop(I32 optype, SV *sv, SV *left, SV *right)
  329. {
  330.     dTHR;    /* just for taint */
  331. #ifdef LIBERAL
  332.     register long *dl;
  333.     register long *ll;
  334.     register long *rl;
  335. #endif
  336.     register char *dc;
  337.     STRLEN leftlen;
  338.     STRLEN rightlen;
  339.     register char *lc;
  340.     register char *rc;
  341.     register I32 len;
  342.     I32 lensave;
  343.     char *lsave;
  344.     char *rsave;
  345.  
  346.     if (sv != left || (optype != OP_BIT_AND && !SvOK(sv) && !SvGMAGICAL(sv)))
  347.     sv_setpvn(sv, "", 0);    /* avoid undef warning on |= and ^= */
  348.     lsave = lc = SvPV(left, leftlen);
  349.     rsave = rc = SvPV(right, rightlen);
  350.     len = leftlen < rightlen ? leftlen : rightlen;
  351.     lensave = len;
  352.     if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) {
  353.     dc = SvPV_force(sv, PL_na);
  354.     if (SvCUR(sv) < len) {
  355.         dc = SvGROW(sv, len + 1);
  356.         (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1);
  357.     }
  358.     }
  359.     else {
  360.     I32 needlen = ((optype == OP_BIT_AND)
  361.             ? len : (leftlen > rightlen ? leftlen : rightlen));
  362.     Newz(801, dc, needlen + 1, char);
  363.     (void)sv_usepvn(sv, dc, needlen);
  364.     dc = SvPVX(sv);        /* sv_usepvn() calls Renew() */
  365.     }
  366.     SvCUR_set(sv, len);
  367.     (void)SvPOK_only(sv);
  368. #ifdef LIBERAL
  369.     if (len >= sizeof(long)*4 &&
  370.     !((long)dc % sizeof(long)) &&
  371.     !((long)lc % sizeof(long)) &&
  372.     !((long)rc % sizeof(long)))    /* It's almost always aligned... */
  373.     {
  374.     I32 remainder = len % (sizeof(long)*4);
  375.     len /= (sizeof(long)*4);
  376.  
  377.     dl = (long*)dc;
  378.     ll = (long*)lc;
  379.     rl = (long*)rc;
  380.  
  381.     switch (optype) {
  382.     case OP_BIT_AND:
  383.         while (len--) {
  384.         *dl++ = *ll++ & *rl++;
  385.         *dl++ = *ll++ & *rl++;
  386.         *dl++ = *ll++ & *rl++;
  387.         *dl++ = *ll++ & *rl++;
  388.         }
  389.         break;
  390.     case OP_BIT_XOR:
  391.         while (len--) {
  392.         *dl++ = *ll++ ^ *rl++;
  393.         *dl++ = *ll++ ^ *rl++;
  394.         *dl++ = *ll++ ^ *rl++;
  395.         *dl++ = *ll++ ^ *rl++;
  396.         }
  397.         break;
  398.     case OP_BIT_OR:
  399.         while (len--) {
  400.         *dl++ = *ll++ | *rl++;
  401.         *dl++ = *ll++ | *rl++;
  402.         *dl++ = *ll++ | *rl++;
  403.         *dl++ = *ll++ | *rl++;
  404.         }
  405.     }
  406.  
  407.     dc = (char*)dl;
  408.     lc = (char*)ll;
  409.     rc = (char*)rl;
  410.  
  411.     len = remainder;
  412.     }
  413. #endif
  414.     {
  415.     switch (optype) {
  416.     case OP_BIT_AND:
  417.         while (len--)
  418.         *dc++ = *lc++ & *rc++;
  419.         break;
  420.     case OP_BIT_XOR:
  421.         while (len--)
  422.         *dc++ = *lc++ ^ *rc++;
  423.         goto mop_up;
  424.     case OP_BIT_OR:
  425.         while (len--)
  426.         *dc++ = *lc++ | *rc++;
  427.       mop_up:
  428.         len = lensave;
  429.         if (rightlen > len)
  430.         sv_catpvn(sv, rsave + len, rightlen - len);
  431.         else if (leftlen > len)
  432.         sv_catpvn(sv, lsave + len, leftlen - len);
  433.         else
  434.         *SvEND(sv) = '\0';
  435.         break;
  436.     }
  437.     }
  438.     SvTAINT(sv);
  439. }
  440.  
  441. OP *
  442. do_kv(ARGSproto)
  443. {
  444.     djSP;
  445.     HV *hv = (HV*)POPs;
  446.     HV *keys;
  447.     register HE *entry;
  448.     SV *tmpstr;
  449.     I32 gimme = GIMME_V;
  450.     I32 dokeys =   (PL_op->op_type == OP_KEYS);
  451.     I32 dovalues = (PL_op->op_type == OP_VALUES);
  452.     I32 realhv = (SvTYPE(hv) == SVt_PVHV);
  453.     
  454.     if (PL_op->op_type == OP_RV2HV || PL_op->op_type == OP_PADHV) 
  455.     dokeys = dovalues = TRUE;
  456.  
  457.     if (!hv) {
  458.     if (PL_op->op_flags & OPf_MOD) {    /* lvalue */
  459.         dTARGET;        /* make sure to clear its target here */
  460.         if (SvTYPE(TARG) == SVt_PVLV)
  461.         LvTARG(TARG) = Nullsv;
  462.         PUSHs(TARG);
  463.     }
  464.     RETURN;
  465.     }
  466.  
  467.     keys = realhv ? hv : avhv_keys((AV*)hv);
  468.     (void)hv_iterinit(keys);    /* always reset iterator regardless */
  469.  
  470.     if (gimme == G_VOID)
  471.     RETURN;
  472.  
  473.     if (gimme == G_SCALAR) {
  474.     IV i;
  475.     dTARGET;
  476.  
  477.     if (PL_op->op_flags & OPf_MOD) {    /* lvalue */
  478.         if (SvTYPE(TARG) < SVt_PVLV) {
  479.         sv_upgrade(TARG, SVt_PVLV);
  480.         sv_magic(TARG, Nullsv, 'k', Nullch, 0);
  481.         }
  482.         LvTYPE(TARG) = 'k';
  483.         if (LvTARG(TARG) != (SV*)keys) {
  484.         if (LvTARG(TARG))
  485.             SvREFCNT_dec(LvTARG(TARG));
  486.         LvTARG(TARG) = SvREFCNT_inc(keys);
  487.         }
  488.         PUSHs(TARG);
  489.         RETURN;
  490.     }
  491.  
  492.     if (!SvRMAGICAL(keys) || !mg_find((SV*)keys,'P'))
  493.         i = HvKEYS(keys);
  494.     else {
  495.         i = 0;
  496.         /*SUPPRESS 560*/
  497.         while (hv_iternext(keys)) i++;
  498.     }
  499.     PUSHi( i );
  500.     RETURN;
  501.     }
  502.  
  503.     EXTEND(SP, HvKEYS(keys) * (dokeys + dovalues));
  504.  
  505.     PUTBACK;    /* hv_iternext and hv_iterval might clobber stack_sp */
  506.     while (entry = hv_iternext(keys)) {
  507.     SPAGAIN;
  508.     if (dokeys)
  509.         XPUSHs(hv_iterkeysv(entry));    /* won't clobber stack_sp */
  510.     if (dovalues) {
  511.         tmpstr = sv_newmortal();
  512.         PUTBACK;
  513.         sv_setsv(tmpstr,realhv ?
  514.              hv_iterval(hv,entry) : avhv_iterval((AV*)hv,entry));
  515.         DEBUG_H(sv_setpvf(tmpstr, "%lu%%%d=%lu",
  516.                 (unsigned long)HeHASH(entry),
  517.                 HvMAX(keys)+1,
  518.                 (unsigned long)(HeHASH(entry) & HvMAX(keys))));
  519.         SPAGAIN;
  520.         XPUSHs(tmpstr);
  521.     }
  522.     PUTBACK;
  523.     }
  524.     return NORMAL;
  525. }
  526.  
  527.